home *** CD-ROM | disk | FTP | other *** search
- /* Main-level network program:
- * initialization
- * keyboard processing
- * generic user commands
- *
- * Copyright 1991 Phil Karn, KA9Q
- * Mods by KO4KS
- */
- #include <stdio.h>
- #include <time.h>
- #if defined(__TURBOC__) && defined(MSDOS)
- #include <fcntl.h>
- #include <dos.h>
- #include <io.h>
- #include <conio.h>
- #include <ctype.h>
- #include <dir.h>
- #endif
- #include "global.h"
- #include "config.h"
- #ifdef ANSIPROTO
- #include <stdarg.h>
- #endif
- #include "mbuf.h"
- #include "timer.h"
- #include "proc.h"
- #include "iface.h"
- #include "ip.h"
- #include "tcp.h"
- #include "udp.h"
- #include "ax25.h"
- #include "kiss.h"
- #include "enet.h"
- #include "netrom.h"
- #include "ftpcli.h"
- #include "telnet.h"
- #include "tty.h"
- #include "session.h"
- #include "hardware.h"
- #include "usock.h"
- #include "socket.h"
- #ifdef LZW
- #include "lzw.h"
- #endif
- #include "cmdparse.h"
- #include "commands.h"
- #include "daemon.h"
- #include "devparam.h"
- #include "domain.h"
- #include "files.h"
- #include "main.h"
- #include "mailbox.h"
- #include "remote.h"
- #include "trace.h"
- #include "mailutil.h"
- #include "smtp.h"
-
- #ifdef XSPAWN
- #include "xspawn.h"
- #endif
-
- extern struct cmds DFAR Cmds[],DFAR Startcmds[],DFAR Stopcmds[],Attab[];
- extern int SYSback, SYSfore;
- extern char vgaDesired;
- extern unsigned char SCREENlength;
-
- extern short NextCmd;
- extern struct session *ScreenOwner; /* Session currently displayed */
-
- #if (!defined(MSDOS) || defined(ESCAPE)) /* PC uses F-10 key always */
- static char Escape = 0x1d; /* default escape character is ^] */
- #endif
-
- #ifdef __TURBOC__
- int dofstat __ARGS((void));
- #endif
- char NoRead[] = "Can't read %s: %s\n";
- char Badhost[] = "Unknown host %s\n";
- char Badinterface[] = "Interface \"%s\" unknown\n";
- char Existingiface[] = "Interface %s already exists\n";
- char Nospace[] = "No space!!\n"; /* Generic malloc fail message */
- #ifdef ITT
- char Nosversion[] = "ITT Tactical MultiNet Gateway\n%s";
- char NosLoadInfo[] = "Load info: CS=0x%04x DS=0x%04x";
- char Prompt[] = "TMNG";
- #else
- #if defined(TNOS) && !defined(ITT)
- char readmeFile[] = "features.new";
- #endif
- extern char DFAR Tnosversion[];
- char Nosversion[] = "KA9Q NOS version %s\n";
- char NosLoadInfo[] = "TNOS load info: CS=0x%04x DS=0x%04x";
- char Prompt[] = "Net";
- #endif
- char Noperm[] = "Permission denied.\n";
- char Nosock[] = "Can't create socket\n";
- char FromSysop[] = "*** Msg from SYSOP: %s\n";
- char SysMessage[] = "System message";
- char *Hostname = NULLCHAR;
- char *Motd = NULLCHAR; /* Message Of The Day */
- int Attended = TRUE; /* default to attended mode */
- int ThirdParty = TRUE; /* Allows 3rd party mail by default */
- int main_exit = FALSE; /* from main program (flag) */
- int Mprunning = 0; /* flag for other parts (domain) to signal
- * that we are fully configured running.
- */
- struct proc *Cmdpp;
- struct proc *Display;
- #ifdef LZW
- int Lzwmode = LZWCOMPACT;
- int16 Lzwbits = LZWBITS;
- #endif
-
- #ifdef TRACE
- int Tracesession = 1;
- struct session *Trace = NULLSESSION;
- #endif
-
- static char PromptType;
-
- static char *DumpAddr = NULL; /* Memory dump pointer */
- static FILE *Logfp;
- time_t StartTime; /* Time that NOS was started */
- static int Verbose;
- char *firstMsg;
- struct hist *Histry; /* command recall stuff */
- int Histrysize;
- int Maxhistory = 10;
- #ifdef TNOS_68K
- extern int Initroot;
- extern int TNOS_68KAlarm;
- extern short UseCurses;
- #endif
-
-
- static void ctohex __ARGS((char *buf,int16 c));
- static void fmtline __ARGS((int16 addr,char *buf,int16 len));
- #ifndef TNOS_68K
- extern void VMSinit (), VMSterm();
- #endif
- extern void displayStatLine __ARGS((int offset));
- extern void statLineToggle (), statlog();
- extern void assign_filenames __ARGS((char *, int));
- static void logcmd __ARGS((char *));
- static void freehistory ();
-
- #ifdef MSDOS
- char cpuid[]={
- 0x52,0x33,0xD2,0x9C,0x58,0x80,0xE4,0x0F,0x50,0x9D,0x9C,
- 0x58,0x80,0xE4,0xF0,0x80,0xFC,0xF0,0x74,0x12,0xFE,0xC2,
- 0x9C,0x58,0x80,0xCC,0xF0,0x50,0x9D,0x9C,0x58,0x80,0xE4,
- 0xF0,0x74,0x02,0xFE,0xC2,0xFE,0xC2,0x8B,0xC2,0x5A,0xCB},
- *cpuname[]={"8088/8086/V20/V30","80286","80386/80486"};
- #endif
-
-
- void netPrompt ()
- {
- char *str;
- switch (PromptType) {
- case 2: str = Command->curdirs->dir;
- break;
- case 1: if (Hostname) {
- str = Hostname;
- break;
- } /* else, fall through */
- default: str = Prompt;
- }
- tprintf ("%s> ", str);
- usflush(Command->output);
- }
-
- int
- main(argc,argv)
- int argc;
- char *argv[];
- {
- char *inbuf,*intmp;
- FILE *fp;
- struct daemon *tp;
- struct mbuf *bp;
- int i;
- int c;
- struct cur_dirs dirs;
- #ifdef MSDOS
- int cpu,(DFAR *CpuId)()=(int (DFAR *)())cpuid;
- #endif
-
- #ifdef XSPAWN
- /* These vectors WILL be intercepted by NOS in COMMAND.ASM
- Go ahead and tell XSPAWN to save their current state, now.
- Vector 0x23 is also used by NOS, but is ALREADY being preserved
- by the XSPAWN routines */
- addvect (8, CURRENT);
- addvect (0x10, CURRENT);
- addvect (0x13, CURRENT);
- addvect (0x1b, CURRENT);
- addvect (0x21, CURRENT);
- addvect (0x24, CURRENT);
- addvect (0x28, CURRENT);
- #endif
- StartTime = time(&StartTime); /* NOS Start_Up time */
- randomize();
-
- while((c = getopt(argc,argv,"k:g:s:f:x:d:o:nbvec")) != EOF){
- switch(c){
-
- #ifdef TRACE
- case 'n': /* No session for tracing */
- Tracesession = 0;
- break;
- #endif
- case 'k': /* background color */
- i= (getcolor (optarg) + 10);
- if (i)
- SYSback = i;
- break;
- case 'g': /* foreground color */
- i = getcolor (optarg);
- if (i)
- SYSfore = i;
- break;
- #ifdef TNOS_68K
- case 'c': /* curses mode */
- UseCurses = 1;
- break;
- #endif
- case 's': /* Number of sockets */
- Nusock = atoi(optarg);
- break;
- case 'f': /* read a filename config file */
- assign_filenames(optarg, 1);
- break;
- #ifdef XSPAWN
- case 'x': /* Path for XSWAP temp file */
- _swappath = strdup(optarg);
- break;
- #endif
- case 'd': /* Root directory for various files */
- initroot(optarg);
- break;
- #ifdef __TURBOC__
- case 'b': /* Use BIOS for screen output */
- directvideo = 0;
- break;
- #endif
- case 'v':
- Verbose = 1;
- break;
- #ifndef TNOS_68K
- case 'e': /* EGA/VGA 43/50 mode desired */
- vgaDesired = 1;
- break;
- #endif
- case 'o': /* override number of interactive sessions */
- Nsessions = atoi (optarg);
- if (Nsessions < 5)
- Nsessions = 5; /* but not less than 5 */
- break;
- }
- }
- #if defined(TNOS) && !defined(TNOS_68K)
- VMSinit ();
- #endif
- #ifdef TNOS_68K
- if (!Initroot)
- initroot ("/dd/nos");
- oskinit();
- #ifdef TRACE
- Tracesession = UseCurses; /* no session trace if dumb terminal mode */
- #endif
- #endif
- intmp = firstMsg; /* we won't report an error here, if it occurs */
- firstMsg = (char *) 0;
- assign_filenames("config.nos", 0); /* automatically look for users config */
- if (firstMsg)
- free (firstMsg);
- firstMsg = intmp;
- #ifdef ITT
- chdir ("/r0");
- #endif
- kinit();
- ipinit();
- ioinit();
- sockinit();
- Cmdpp = mainproc("cmdintrp");
-
- Sessions = (struct session *)callocw(Nsessions,sizeof(struct session));
- for (i = 0; i < Nsessions; i++)
- Sessions[i].index = i;
- #ifdef TRACE
- if(Tracesession)
- Trace = newsession(NULLCHAR,TRACESESSION,0);
- #endif
- ScreenOwner = Command = Lastcurr = newsession(NULLCHAR,COMMAND,0);/*"command int" not needed*/
- /* Flow mode is set AFTER we've read the autoexec file !
- * this keeps systems from locking up if the reboot is unattended - WG7J
- */
- #ifndef TNOS_68K
- Display = newproc("display",250,display,0,NULLCHAR,NULL,0);
- #else
- Display = newproc("display",512,display,0,NULLCHAR,NULL,0);
- #endif
- setscreens (0, 0, 1);
- if (firstMsg) {
- tputs (firstMsg);
- free (firstMsg);
- }
- #if defined(TNOS) && !defined(ITT)
- tprintf(Tnosversion);
- #else
- tprintf(Nosversion,Version);
- #endif
- #ifndef ITT
- tputs(Version2);
- tputs("Copyright 1991 by Phil Karn (KA9Q) and contributors.\n");
- #else
- tputs ("\n\n");
- #endif
- #ifdef MSDOS
- cpu=(*CpuId)();
- tprintf("Processor detected: %s\n",cpuname[cpu-1]);
- #endif
- rflush();
-
- usercvt();
- /* Start background Daemons */
- for(tp=Daemons;;tp++){
- if(tp->name == NULLCHAR)
- break;
- newproc(tp->name,tp->stksize,tp->fp,0,NULLCHAR,NULL,0);
- }
-
- init_dirs(&dirs);
- Command->curdirs=&dirs;
-
- #if defined(TNOS) && !defined(ITT)
- if(!access (readmeFile, 4)) {
- int row;
- char *args[2];
- args[1] = readmeFile;
- tprintf ("\nWould you like to view the '%s' file, containing information\non the new features for this version of TNOS?\n", readmeFile);
- Command->ttystate.edit = Command->ttystate.echo = 0;
- row = keywait("Yes or No [y/n]? ",0);
- Command->ttystate.edit = Command->ttystate.echo = 1;
- if (row == 'Y' || row == 'y')
- doview (2, args, 0);
- tputc ('\n');
- }
- #endif
-
- if(optind < argc){
- /* Read startup file named on command line */
- if((fp = fopen(argv[optind],READ_TEXT)) == NULLFILE)
- tprintf(NoRead,argv[optind],sys_errlist[errno]);
- } else {
- /* Read default startup file named in files.c (autoexec.nos) */
- if((fp = fopen(Startup,READ_TEXT)) == NULLFILE)
- tprintf(NoRead,Startup,sys_errlist[errno]);
- }
- if(fp != NULLFILE){
- inbuf = mallocw(BUFSIZ);
- intmp = mallocw(BUFSIZ);
- while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
- strcpy(intmp,inbuf);
- if(Verbose){
- tprintf("%s",intmp);
- rflush();
- }
- if(cmdparse(Cmds,inbuf,NULL) != 0){
- tprintf("input line: %s",intmp);
- }
- }
- fclose(fp);
- free(inbuf);
- free(intmp);
- }
-
- Mprunning = 1; /* we are on speed now */
- Command->flowmode = 1; /* set 'more' paging on command screen */
-
- /* Now loop forever, processing commands */
- for(;;){
- netPrompt ();
- if(recv_mbuf(Command->input,&bp,0,NULLCHAR,0) != -1){
- logcmd(bp->data);
- (void)cmdparse(Cmds,bp->data,Lastcurr);
- free_p(bp);
- }
- }
- }
-
-
- int
- chksession (sp)
- struct session *sp;
- {
- return (((sp->type != COMMAND) && (sp != Trace) && (sp->type != FREE)) ? 1 : 0);
- }
-
-
- /* Keyboard input process */
- /* Modified to support F-key session switching,
- * from the WNOS3 sources - WG7J
- */
- void
- keyboard(i,v1,v2)
- int i;
- void *v1;
- void *v2;
- {
- int c;
- struct mbuf *bp;
- register int j,k;
- struct session *sp;
- int got = 0;
-
- /* Keyboard process loop */
- for(;;){
- c = kbread();
- #if (!defined(MSDOS) || defined(ESCAPE))
- if(c == Escape && Escape != 0)
- c = -2;
- #endif
- if(c == -2 && Current != Command){
- /* Save current tty mode and set cooked */
- /* swapscreen(Current,Command); */
- Lastcurr = Current;
- Current = Command;
- swapscreen(Lastcurr,Current);
- /* displayStatLine (0L); */
- /* set 'more' paging on command screen */
- Command->flowmode = 1;
- }
- if(c < -2) { /* F1 to F9 (or INSERT) pressed */
- switch (c) {
- #ifdef TRACE
- case -11: /* If F9 is pressed, -11 is returned and we swap to Trace - WG7J */
- if(Tracesession) {
- if(Current != Trace){
- /* Save current tty mode and set cooked */
- /* swapscreen(Current,Trace); */
- Lastcurr = Current;
- Current = Trace;
- swapscreen(Lastcurr,Current);
- /* turn off 'more' paging on trace screen */
- Trace->flowmode = 0;
- } else {
- /* Toggle back to previous session */
- /* swapscreen(Trace,Lastcurr); */
- Current = Lastcurr;
- Lastcurr = Trace;
- swapscreen(Lastcurr,Current);
- }
- }
- break;
- #endif
- case -105: /* INSERT pressed, statline toggle */
- statLineToggle ();
- break;
- case -106: /* DEL pressed, toggle flow control */
- Current->flowmode ^= 1;
- break;
- case -107: /* HOME pressed, kick current session */
- dokick (0, 0, Current);
- break;
- case -108: /* END pressed, end current session */
- doreset (0, 0, Current);
- break;
- case -109: /* PGUP pressed, goto previous session */
- j = (Current->index - 1) ? Current->index - 1 : Nsessions - 1;
- for(sp = &Sessions[j]; sp > Sessions; sp--)
- if ((got = chksession (sp)) != NULL)
- break;
- if (!got)
- for(sp = &Sessions[Nsessions - 1]; sp > Current; sp--)
- if ((got = chksession (sp)) != NULL)
- break;
- if (got) {
- /* swapscreen(Current,sp); */
- Lastcurr = Current;
- Current = sp;
- swapscreen(Lastcurr,Current);
- }
- break;
- case -110: /* PGDN pressed, goto next session */
- for(sp = &Sessions[Current->index + 1]; sp < &Sessions[Nsessions]; sp++)
- if ((got = chksession (sp)) != NULL)
- break;
- if (!got)
- for(sp = Sessions; sp < Current; sp++)
- if ((got = chksession (sp)) != NULL)
- break;
- if (got) {
- /* swapscreen(Current,sp); */
- Lastcurr = Current;
- Current = sp;
- swapscreen(Lastcurr,Current);
- }
- break;
- default:
- k = (-1 * c) - 2;
- for(sp = Sessions, j = 0; sp < &Sessions[Nsessions]; sp++) {
- if(sp->type == COMMAND)
- continue;
- j++;
- if(sp->type != FREE && j == k) {
- /* swapscreen(Current,sp); */
- Lastcurr = Current;
- Current = sp;
- swapscreen(Lastcurr,Current);
- break;
- }
- }
- }
- }
-
- /* Current->row = MOREROWS; */
- Current->row = SCREENlength - 1 - (Current->split * 2);
- psignal(&Current->row,1);
- if(c >= 0){
- /* If the screen driver was in morewait state, this char
- * has woken him up. Toss it so it doesn't also get taken
- * as normal input. If the char was a command escape,
- * however, it will be accepted; this gives the user
- * a way out of lengthy output.
- */
- if(!Current->morewait
- && (bp = ttydriv(Current,c)) != NULLBUF){
- send_mbuf(Current->input,bp,0,NULLCHAR,0);
- }
- }
- }
- }
-
- extern int Kblocked;
- extern char *Kbpasswd;
- #ifdef LOCK
-
- /*Lock the keyboard*/
- int
- dolock(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
-
- extern char Noperm[];
-
- /*allow only keyboard users to access the lock command*/
- if(Curproc->input != Command->input) {
- tputs(Noperm);
- return 0;
- }
- if(argc == 1) {
- if(Kbpasswd == NULLCHAR)
- tputs("Set password first\n");
- else {
- Kblocked = 1;
- tputs("Keyboard locked\n");
- Command->ttystate.echo = 0; /* Turn input echoing off! */
- }
- return 0;
- }
- if(argc == 3) {
- if(*argv[1] == 'p') { /*set the password*/
- if(Kbpasswd != NULLCHAR){
- free(Kbpasswd);
- Kbpasswd = NULLCHAR; /* reset the pointer */
- }
- if(!strlen(argv[2]))
- return 0; /* clearing the buffer */
- Kbpasswd = strdup(argv[2]);
- return 0;
- }
- }
-
- tputs("Usage: lock password \"<unlock password>\"\nor 'lock' to lock the keyboard\n");
-
- return 0;
- }
-
- #endif
-
- /* Choose the prompt type */
- int
- doprompt(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char *str;
-
- if(argc == 1) {
- switch (PromptType) {
- case 2: str = "Dirname";
- break;
- case 1: str = "Hostname";
- break;
- default: str = "Normal";
- }
- tprintf ("Prompt: %s\n", str);
- return 0;
- }
- if(*argv[1] == 'h') /* use the hostname */
- PromptType = 1;
- else if (*argv[1] == 'd') /* use the dirname */
- PromptType = 2;
- else if (*argv[1] == 'n') /* use the normal prompt */
- PromptType = 0;
- else
- tputs("Usage: prompt [hostname | dirname | normal]\n");
- return 0;
- }
-
- #ifdef ALLCMD
- /* Standard commands called from main */
- int
- dodelete(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i;
- char filenm[13], *cp, fullname[128];
- unsigned attr;
- char fname[128];
-
- for(i=1;i < argc; i++) {
- strcpy(fname,make_fname(Command->curdirs->dir,argv[i]));
- if (!_dos_getfileattr (fname, &attr) && (attr & FA_DIREC)) {
- strcat (fname, "/*.*");
- tputs ("All files in directory will be deleted!\nAre you sure (Y/N)? ");
- usflush(Curproc->output);
- recvline (Curproc->input, filenm, 13);
- if (toupper (*filenm) != 'Y')
- continue;
- cp = (char *) 1;
- }
- filedir(fname, 0, filenm);
- if ((cp = strrchr (fname, '/')) != NULLCHAR)
- *cp = 0;
- for ( ; *filenm; filedir (fname, 1, filenm)) {
- if (*filenm == '.' && (!filenm[1] || (filenm[1] == '.' && !filenm[2])))
- continue;
- sprintf (fullname, "%s%s%s", (cp) ? fname : "", (cp) ? "/" : "", filenm);
- if(unlink(fullname) == -1)
- tprintf("Can't delete %s: %s\n", fullname,sys_errlist[errno]);
- }
- }
- return 0;
- }
-
-
- int
- dorename(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char fname1[128];
- char fname2[128];
-
- strcpy(fname1,make_fname(Command->curdirs->dir,argv[1]));
- strcpy(fname2,make_fname(Command->curdirs->dir,argv[2]));
- if(rename(fname1,fname2) == -1)
- tprintf("Can't rename: %s\n",sys_errlist[errno]);
- return 0;
- }
-
-
- int
- docopy(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- register FILE *old, *new;
- register int ch;
- register unsigned char count;
- unsigned attr;
- char filenm[13], *dirnam = NULL, *cp, fullname[512];
- int usedir = 0;
- char fname[128], fname2[128];
-
- if (argc > 2) {
- strcpy(fname2,make_fname(Command->curdirs->dir,argv[2]));
- _dos_getfileattr (fname2, &attr);
- if(attr & FA_DIREC) {
- usedir = 1;
- dirnam = fname2;
- }
- } else
- usedir = 1;
- strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
- if (!_dos_getfileattr (fname, &attr) && (attr & FA_DIREC)) {
- strcat (fname, "/*.*");
- cp = (char *) 1;
- }
- filedir (fname, 0, filenm);
- if ((cp = strrchr (fname, '/')) != NULLCHAR)
- *cp = 0;
- for ( ; *filenm; filedir (fname, 1, filenm)) {
- if (*filenm == '.' && (!filenm[1] || (filenm[1] == '.' && !filenm[2])))
- continue;
- sprintf (fullname, "%s%s%s", (cp) ? fname : "", (cp) ? "/" : "", filenm);
- if((old = fopen(fullname,READ_BINARY)) == NULL) {
- tprintf("Can't open %s: %s\n",fullname,sys_errlist[errno]);
- continue;
- }
- sprintf (fullname, "%s%s%s", (dirnam) ? dirnam : "", (dirnam) ? "/" : "", (usedir) ? filenm : fname2);
- if((new = fopen(fullname,WRITE_BINARY)) == NULL) {
- tprintf("Can't open %s: %s\n",fullname,sys_errlist[errno]);
- fclose (old);
- continue;
- }
- strlwr (fullname);
- tprintf ("Copying '%s'...\n", fullname);
- /* Now go copy */
- count = 0;
- while((ch = fgetc(old)) != EOF) {
- fputc(ch,new);
- if(!(++count)) /* be polite to other users */
- pwait(NULL);
- }
- fclose(old);
- fclose(new);
- if (!usedir)
- break;
- }
- return 0;
- }
- #endif /*ALLCMD*/
-
- /*this is also called from the remote-server for the 'exit' command - WG7J*/
- void
- where_outta_here(resetme)
- int resetme;
- {
- int i;
- time_t StopTime;
- FILE *fp;
- char *inbuf,*intmp;
-
- if (NextCmd)
- NextCmd = 1;
- /* inbuf = NextCmdMsg;
- NextCmdMsg = NULLCHAR;
- free (inbuf); */
-
- /* Execute sequence of commands taken from file "~/onexit.nos" */
- /* From iw0cnb */
- if((fp = fopen(Onexit,READ_TEXT)) != NULLFILE){
- inbuf = mallocw(BUFSIZ);
- intmp = mallocw(BUFSIZ);
- while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
- strcpy(intmp,inbuf);
- if(Verbose){
- tprintf("%s",intmp);
- rflush();
- }
- if(cmdparse(Cmds,inbuf,NULL) != 0){
- tprintf("input line: %s",intmp);
- }
- }
- fclose(fp);
- free(inbuf);
- free(intmp);
- }
- StopTime = time(&StopTime);
- main_exit = TRUE; /* let everyone know we're out of here */
- reset_all();
- if(Dfile_updater != NULLPROC)
- alert(Dfile_updater,0); /* don't wait for timeout */
- for(i=0;i<100;i++)
- pwait(NULL); /* Allow tasks to complete */
- #ifdef TRACE
- shuttrace();
- #endif
- #if defined(TNOS) && !defined(TNOS_68K)
- VMSterm ();
- #endif
- log(-1,"TNOS was stopped");
- if(Logfp){
- fclose(Logfp);
- Logfp = NULLFILE;
- }
- iostop();
- if(resetme)
- sysreset();
- freehistory ();
- free_dirs(Command->curdirs);
- #ifdef TNOS_68K
- alm_delete (TNOS_68KAlarm);
- #endif
- exit(0);
- }
-
- int
- doexit(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int c;
- struct mbuf *bp;
-
- if(Curproc->input != Command->input)
- return -2; /*probably mailbox-sysop */
- tputs ("\007Exit TNOS: Are you sure? ");
- tflush ();
- recv_mbuf(Command->input,&bp,0,NULLCHAR,0);
- c = bp->data[0];
- if(c != 'y' && c != 'Y')
- return 0; /* signal delete of message */
- where_outta_here(0); /*No reset!*/
- return 0; /* To satisfy lint */
- }
-
- int
- dohostname(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc < 2)
- tprintf("%s\n",Hostname);
- else {
- struct iface *ifp;
- char *name;
-
- if((ifp = if_lookup(argv[1])) != NULLIF){
- if((name = resolve_a(ifp->addr, FALSE)) == NULLCHAR){
- tprintf("Interface address not resolved\n");
- return 1;
- } else {
- if(Hostname != NULLCHAR)
- free(Hostname);
- Hostname = name;
- tprintf("Hostname set to %s\n", name );
- }
- } else {
- if(Hostname != NULLCHAR)
- free(Hostname);
- Hostname = strdup(argv[1]);
- /* Remove trailing dot */
- if(Hostname[strlen(Hostname)] == '.')
- Hostname[strlen(Hostname)] = '.';
- }
- }
- return 0;
- }
-
- int
- dolog(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- static char *logname;
- char fname[128];
-
- if(argc < 2){
- if(Logfp)
- tprintf("Logging to %s\n",logname);
- else
- tprintf("Logging off\n");
- return 0;
- }
- if(Logfp){
- log(-1,"TNOS log closed");
- fclose(Logfp);
- Logfp = NULLFILE;
- free(logname);
- logname = NULLCHAR;
- }
- if(strcmp(argv[1],"stop") && strcmp(argv[1], "off")){
- strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
- logname = strdup(fname);
- Logfp = fopen(logname,APPEND_TEXT);
- log(-1,"TNOS v%s was started at %s", Version, ctime(&StartTime));
- #ifdef MSDOS
- log(-1,NosLoadInfo, _CS, _DS);
- #endif
- }
- return 0;
- }
-
-
- /* Attach an interface
- * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
- */
- int
- doattach(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return subcmd(Attab,argc,argv,p);
- }
- /* Manipulate I/O device parameters */
- int
- doparam(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int param,set;
- int32 val;
- register struct iface *ifp;
-
- if((ifp = if_lookup(argv[1])) == NULLIF){
- tprintf(Badinterface,argv[1]);
- return 1;
- }
- if(ifp->ioctl == NULL){
- tprintf("Not supported\n");
- return 1;
- }
- if(argc < 3){
- for(param=1;param<=16;param++){
- val = (*ifp->ioctl)(ifp,param,FALSE,0L);
- if(val != -1)
- tprintf("%s: %ld\n",parmname(param),val);
- }
- return 0;
- }
- param = devparam(argv[2]);
- if(param == -1){
- tprintf("Unknown parameter %s\n",argv[2]);
- return 1;
- }
- if(argc < 4){
- set = FALSE;
- val = 0L;
- } else {
- set = TRUE;
- val = atol(argv[3]);
- }
- val = (*ifp->ioctl)(ifp,param,set,val);
- if(val == -1)
- tprintf("Parameter %s not supported\n",argv[2]);
- else
- tprintf("%s: %ld\n",parmname(param),val);
- return 0;
- }
-
- /* Display or set IP interface control flags */
- int
- domode(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- register struct iface *ifp;
-
- if((ifp = if_lookup(argv[1])) == NULLIF){
- tprintf(Badinterface,argv[1]);
- return 1;
- }
- if(argc < 3){
- tprintf("%s: %s\n",ifp->name,
- (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
- return 0;
- }
- switch(argv[2][0]){
- case 'v':
- case 'c':
- case 'V':
- case 'C':
- ifp->flags |= CONNECT_MODE;
- break;
- case 'd':
- case 'D':
- ifp->flags &= ~CONNECT_MODE;
- break;
- default:
- tprintf("Usage: %s [vc | datagram]\n",argv[0]);
- return 1;
- }
- return 0;
- }
-
- #if (!defined(MSDOS) || defined(ESCAPE))
- int
- doescape(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc < 2)
- tprintf("0x%x\n",Escape);
- else
- Escape = *argv[1];
- return 0;
- }
- #endif MSDOS
- /* Generate system command packet. Synopsis:
- * remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
- */
- int
- doremote(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct sockaddr_in fsock;
- int s,c;
- char *data,x;
- int16 port,len;
- char *key = NULLCHAR;
- int klen;
- int32 addr = 0;
- char *cmd,*host;
-
- port = IPPORT_REMOTE; /* Set default */
- optind = 1; /* reinit getopt() */
- while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
- switch(c){
- case 'a':
- if((addr = resolve(optarg)) == 0){
- tprintf("Host %s unknown\n",optarg);
- return -1;
- }
- break;
- case 'p':
- port = atoi(optarg);
- break;
- case 'k':
- key = optarg;
- klen = strlen(key);
- break;
- case 's':
- Rempass = strdup(optarg);
- return 0; /* Only set local password */
- }
- }
- if(optind > argc - 2){
- tprintf("Insufficient args\n");
- return -1;
- }
- host = argv[optind];
- cmd = argv[optind + 1];
- if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
- tprintf("socket failed\n");
- return 1;
- }
- len = 1;
- /* Did the user include a password or kickme target? */
- if(addr != 0 && cmd[0] == 'k')
- len += sizeof(int32);
-
- if(key != NULLCHAR && (cmd[0] == 'r' || cmd[0] == 'e'))
- len += klen;
-
- if(len == 1)
- data = &x;
- else
- data = mallocw(len);
-
- fsock.sin_family = AF_INET;
- if((fsock.sin_addr.s_addr = resolve(host)) == 0){
- tprintf("Host %s unknown\n",host);
- goto cleanup;
- }
- fsock.sin_port = port;
-
- switch(cmd[0]){
- case 'r':
- data[0] = SYS_RESET;
- if(key != NULLCHAR)
- strncpy(&data[1],key,klen);
- break;
- case 'e':
- data[0] = SYS_EXIT;
- if(key != NULLCHAR)
- strncpy(&data[1],key,klen);
- break;
- case 'k':
- data[0] = KICK_ME;
- if(addr != 0)
- put32(&data[1],addr);
- break;
- default:
- tprintf("Unknown command %s\n",cmd);
- goto cleanup;
- }
- /* Form the command packet and send it */
- if(sendto(s,data,len,0,(char *)&fsock,sizeof(fsock)) == -1){
- tprintf("sendto failed: %s\n",sys_errlist[errno]);
- goto cleanup;
- }
- cleanup:
- if(data != &x)
- free(data);
- close_s(s);
- return 0;
- }
-
- #if (defined(ALLCMD) || defined(ALLSESSIONS))
- int
- morecmd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct session *sp;
- FILE *fp;
- char buf[81];
- char fname[256];
- int row;
-
- int usesession = 0;
-
- /* Use a session if this comes from console - WG7J*/
- if(Curproc->input == Command->input) {
- usesession = 1;
- if((sp = newsession(argv[1],MORE,0)) == NULLSESSION){
- return 1;
- }
- /* Put tty into raw mode so single-char responses will work */
- sp->ttystate.echo = sp->ttystate.edit = 0;
- row = SCREENlength;
- }
-
- strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
- if((fp = fopen(fname,READ_TEXT)) == NULLFILE){
- tprintf(NoRead,fname,sys_errlist[errno]);
- if(usesession) {
- keywait(NULLCHAR,1);
- freesession(sp);
- }
- return 1;
- }
- while(fgets(buf,sizeof(buf),fp),!feof(fp)){
- if((argc < 3) || (strstr(buf,argv[2])!=NULLCHAR)) {
- tprintf("%s",buf);
- if(usesession) {
- if(--row == 0){
- row = keywait("--More--",0);
- switch(row){
- case -1:
- case 'q':
- case 'Q':
- case 'n':
- case 'N':
- goto done;
- #ifndef TNOS_68K
- case '\n':
- #else
- case '\l':
- #endif
- case '\r':
- row = 1;
- break;
- case ' ':
- default:
- /* row = Numrows - 1; */
- row = SCREENlength;
- }
- }
- }
- }
- }
- done: fclose(fp);
- if(usesession) {
- keywait(NULLCHAR,1);
- freesession(sp);
- }
- return 0;
- }
-
- int
- domore(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char **pargv;
- int i;
-
- if(Curproc->input == Command->input) {
- /* Make private copy of argv and args,
- * spawn off subprocess and return.
- */
- pargv = (char **)callocw(argc + 1,sizeof(char *));
- for(i=0;i<argc;i++)
- pargv[i] = strdup(argv[i]);
- pargv[i] = NULL;
- newproc("more",512,(void (*)())morecmd,argc,(void *)pargv,p,1);
- } else
- morecmd(argc,argv,p);
- return 0;
- }
-
-
-
- int
- dotail(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- register int handle, i;
- register unsigned line = 0, rdsize = 2000;
- long length;
- char *buffer, fname[128];
- register int numlines = 18;
-
- if (argc == 3) {
- numlines = atoi (argv[2]);
- if (!numlines)
- numlines = 18;
- else
- rdsize = numlines * 100;
- }
- buffer = callocw(rdsize, sizeof (char));
-
- strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
- if ((handle = open (fname, O_BINARY | O_RDONLY)) == -1) {
- tprintf(NoRead,fname,sys_errlist[errno]);
- free(buffer);
- return -1;
- }
- length = filelength (handle);
-
- if (length > rdsize) {
- length -= rdsize;
- } else {
- rdsize = (int) length;
- length = 0;
- }
-
- lseek (handle, length, SEEK_SET);
- if (read (handle, buffer, rdsize) == -1) {
- tprintf(NoRead,fname,sys_errlist[errno]);
- close(handle);
- free(buffer);
- return -1;
- }
-
- for (i = rdsize - 1; i > 0; i--) {
- if (buffer[i] == '\n')
- line++;
- if (line == numlines)
- break;
- }
- for (; i < rdsize; i++)
- tputc(buffer[i]);
-
- tprintf("\n");
- close(handle);
- free(buffer);
- return 0;
- }
- #endif /*ALLCMD*/
-
- /* No-op command */
- int
- donothing(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return 0;
- }
-
- int dosystime(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- long t;
-
- /* Get current time */
- time(&t);
-
- /* Print it */
- tprintf("System time at %s: %s",Hostname, ctime(&t));
- return 0;
- }
-
-
- static int SendError = 1;
-
- int doerror(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&SendError,"Mail errors",argc,argv);
- }
-
- /* Mail a system message to the sysop - WG7J */
- void
- mail_error(char *fmt, ...)
- {
- FILE *txt;
- va_list ap;
- char *cp;
- long t;
- char fn[128];
-
- if(!SendError)
- return;
-
- /* Create the data file */
- if((txt = tmpfile()) == NULL)
- return;
-
- /* Get current time */
- time(&t);
-
- /* Print the text body */
- cp = ctime(&t);
- fprintf(txt,"On %s",cp);
- va_start(ap,fmt);
- vfprintf(txt,fmt,ap);
- va_end(ap);
- fputc('\n',txt);
- rewind (txt);
- rdaemon (txt, NULLCHAR, NULLCHAR, SysMessage, 'P', 0);
-
- fclose(txt);
-
- /* Now kick the smtp server */
- smtptick(NULL);
- }
-
- /* Log messages of the form
- * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
- */
- #if defined(ANSIPROTO)
- void
- log(int s,char *fmt, ...)
- {
- va_list ap;
- char *cp;
- long t;
- int i;
- struct sockaddr fsocket;
- #ifdef MSDOS
- int fd;
- #endif
- char buf[80];
-
- va_start(ap,fmt);
- vsprintf(buf,fmt,ap);
- va_end(ap);
- statlog (buf);
-
- if(Logfp == NULLFILE)
- return;
-
- time(&t);
- cp = ctime(&t);
- rip(cp);
- i = SOCKSIZE;
- fprintf(Logfp,"%s",cp);
- if(getpeername(s,(char *)&fsocket,&i) != -1)
- fprintf(Logfp," %s",psocket(&fsocket));
-
- fprintf(Logfp," - %s\n", buf);
- fflush(Logfp);
- #ifdef MSDOS
- /* MS-DOS doesn't really flush files until they're closed */
- fd = fileno(Logfp);
- if((fd = dup(fd)) != -1)
- close(fd);
- #endif
-
- }
- #else
- /*VARARGS2*/
- void
- log(s,fmt,arg1,arg2,arg3,arg4,arg5)
- int s;
- char *fmt;
- int arg1,arg2,arg3,arg4,arg5;
- {
- char *cp;
- long t;
- int fd,i;
- struct sockaddr fsocket;
- char buf[80];
-
- sprintf(buf,fmt,arg1,arg2,arg3,arg4,arg5);
- statlog (buf);
-
- if(Logfp == NULLFILE)
- return;
- time(&t);
- cp = ctime(&t);
- rip(cp);
- i = SOCKSIZE;
- fprintf(Logfp,"%s",cp);
- if(getpeername(s,(char *)&fsocket,&i) != -1)
- fprintf(Logfp," %s",psocket(&fsocket));
-
- fprintf(Logfp," - %s\n", buf);
- fflush(Logfp);
- #ifdef MSDOS
- /* MS-DOS doesn't really flush files until they're closed */
- fd = fileno(Logfp);
- if((fd = dup(fd)) != -1)
- close(fd);
- #endif
- }
- #endif
-
- int
- dosource(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int linenum = 0;
- char *inbuf,*intmp;
- FILE *fp;
- char fname[128];
-
- /* Read command source file */
- strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
- if((fp = fopen(fname,READ_TEXT)) == NULLFILE){
- tprintf(NoRead,fname,sys_errlist[errno]);
- return 1;
- }
-
- inbuf = malloc(BUFSIZ);
- intmp = malloc(BUFSIZ);
- while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
- strcpy(intmp,inbuf);
- linenum++;
- if(Verbose)
- tprintf("%s",intmp);
- if(cmdparse(Cmds,inbuf,NULL) != 0){
- tprintf("*** file \"%s\", line %d: %s\n",
- argv[1],linenum,intmp);
- }
- }
- fclose(fp);
- free(inbuf);
- free(intmp);
- return 0;
- }
-
- /* if unattended mode is set - restrict ax25, telnet and maybe other sessions */
- doattended(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&Attended,"Attended flag",argc,argv);
- }
-
- /* if ThirdParty is not set - restrict the mailbox (S)end command to local only */
- dothirdparty(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&ThirdParty,"Third-Party mail flag",argc,argv);
- }
-
- #ifdef ALLCMD
- int
- domdump(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- unsigned int i;
- char * addr;
- unsigned int len = 8 * 16; /* default is 8 lines of hex dump */
-
- if(argc < 2 || argc > 3) {
- tprintf("Usage:- dump <hex-address | .> [decimal-range] \n");
- return 0;
- }
- if(argv[1][0] == '.')
- addr = DumpAddr; /* Use last end address */
- else
- addr = ltop(htol(argv[1])); /* get address of item being dumped */
-
- if(argc == 3) {
- len = atoi(argv[2]);
- len = ((len + 15) >> 4) << 4; /* round up to modulo 16 */
- }
-
- if(len < 1 || len > 256) {
- tprintf("Invalid dump range. Valid is 1 to 256\n");
- return 0;
- }
- #ifndef TNOS_68K
- tprintf(" Main Memory Dump Of Location %Fp\n", addr);
- #else
- tprintf(" Main Memory Dump Of Location %08x\n", addr);
- #endif
- tprintf("Addr (offset) Hexadecimal Ascii\n");
- tprintf("---- ----------- -----\n");
-
- for(i = 0; i < len; i += 16)
- fmtline(i, (char *)(addr + i), 16);
- DumpAddr = (char *)(addr + i); /* update address */
- return 0;
- }
-
- /* Print a buffer up to 16 bytes long in formatted hex with ascii
- * translation, e.g.,
- * 0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?
- */
- static void
- fmtline(addr,buf,len)
- int16 addr;
- char *buf;
- int16 len;
- {
- char line[81];
- register char *aptr,*cptr;
- register char c;
-
- memset(line,' ',sizeof(line));
- ctohex(line,(int16)hibyte(addr));
- ctohex(line+2,(int16)lobyte(addr));
- aptr = &line[6];
- cptr = &line[55];
- while(len-- != 0){
- c = *buf++;
- ctohex(aptr,(int16)uchar(c));
- aptr += 3;
- c &= 0x7f;
- if((c > 0x1f) && (c < 0x7f))
- *cptr++ = c;
- else
- *cptr++ = '.';
- }
- *cptr++ = '\0';
- tprintf("%s\n",line);
- }
- /* Convert byte to two ascii-hex characters */
- static void
- ctohex(buf,c)
- register char *buf;
- register int16 c;
- {
- static char hex[] = "0123456789abcdef";
-
- *buf++ = hex[hinibble(c)];
- *buf = hex[lonibble(c)];
- }
- #endif
-
- int
- dowrite(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i,s;
- struct mbx *m;
-
- if((s = atoi(argv[1])) == 0) { /* must be a name */
- /* check the mailbox users */
- for(i = 0; i < NUMMBX; i++){
- if((m = Mbox[i]) != NULLMBX){
- if(!strcmp(m->name,argv[1]))
- break;
- }
- }
- if(i == NUMMBX)
- return 0;
- s = m->user;
- }
- usprintf(s,FromSysop,argv[2]);
- usflush(s);
-
- return 0;
- }
-
- extern void conversWriteall __ARGS((char *str));
-
- /* write a message to all nodeshell users
- * argv[1] is the message.
- */
- int
- dowriteall(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- register struct mbx *m;
- int i;
-
- for(i = 0; i < NUMMBX; i++)
- if((m = Mbox[i]) != NULLMBX){
- usprintf(m->user,FromSysop,argv[1]);
- usflush(m->user);
- }
- #ifdef CONVERS
- conversWriteall (argv[1]);
- #endif
- return 0;
- }
-
-
- int
- dostatus(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- time_t nowtime, elapsedtime;
- unsigned int days,hrs,mins,secs;
-
- nowtime = time(&nowtime); /* current time */
- elapsedtime = nowtime - StartTime; /* nos elapsed time */
-
- tprintf(Nosversion,Version);
- tputs(Version2);
-
- #ifdef MSDOS
- tprintf(NosLoadInfo, _CS, _DS);
- #endif
- tprintf("\nThe system time is %s", ctime(&nowtime));
- tprintf("TNOS was started on %s\n", ctime(&StartTime));
- secs = elapsedtime % 60;
- elapsedtime = elapsedtime / 60;
- mins = elapsedtime % 60;
- elapsedtime = elapsedtime / 60;
- hrs = elapsedtime % 24;
- elapsedtime = elapsedtime / 24;
- days = elapsedtime;
- tprintf("Elapsed time => %u days:%02u hours:%02u minutes:%02u seconds.\n\n",days,hrs,mins,secs);
- tprintf("Sessions = %-d, Sockets = %-d\n\n", Nsessions, Nusock);
- #ifdef ALLCMD
- tprintf("The station is currently %sttended.\n", Attended ? "A" : "Una");
- tprintf("The 'Message Of The Day' is ");
- if(Motd != NULLCHAR)
- tprintf("\n%s",Motd);
- else
- tprintf("not set!\n");
- #endif
- #ifdef __TURBOC__
- dofstat(); /* print status of open files */
- #endif
- return 0;
- }
-
- #ifdef ALLCMD
- int
- domotd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc > 2) {
- tprintf("Usage: motd \"<your message>\"\n");
- return 1;
- }
-
- if(argc < 2) {
- if(Motd != NULLCHAR)
- tprintf("%s",Motd);
- } else {
- if(Motd != NULLCHAR){
- free(Motd);
- Motd = NULLCHAR; /* reset the pointer */
- }
-
- if(!strlen(argv[1]))
- return 0; /* clearing the buffer */
-
- Motd = mallocw(strlen(argv[1])+5); /* allow for the EOL char etc */
- strcpy(Motd, argv[1]);
- strcat(Motd, "\n"); /* add the EOL char */
- }
- return 0;
- }
- #endif /*ALLCMD*/
-
- #ifdef nope
- /* test the stktrace utility */
- int dotest(int argc, char *argv[], void *p) {
-
- void *ptr = (void *) 0x12345678;
- free(ptr);
- return 0;
- }
- #endif
-
- #ifdef __TURBOC__
- /*
- * Fstat utility code.
- * Converted to go into NOS by Kelvin Hill - G1EMM April 9, 1990
- */
-
- extern unsigned char _osmajor;
-
- static char *localcopy __ARGS((char DFAR *));
- static char *progname __ARGS((unsigned int));
-
- int
- dofstat()
- {
- union REGS regs;
- struct SREGS segregs;
- char DFAR *pfiletab, DFAR * pnext, DFAR * fp;
- char DFAR *name, file[13], DFAR * plist, DFAR * entry;
- char ownername[9], ownerext[5];
- int nfiles, i, j, numhandles, entrylen;
- unsigned int access, devinfo, progpsp;
- long length, offset;
- int heading = 0;
-
- regs.h.ah = 0x52; /* DOS list of lists */
- intdosx(®s, ®s, &segregs);
-
- /* make a pointer to start of master list */
- plist = (char DFAR *) MK_FP(segregs.es, regs.x.bx);
-
- /* pointer to start of file table */
- pfiletab = (char DFAR *) MK_FP(*(int DFAR *) (plist + 6), *(int DFAR *) (plist + 4));
-
- switch (_osmajor) {
- case 2:
- entrylen = 40; /* DOS 2.x */
- break;
- case 3:
- entrylen = 53; /* DOS 3.x */
- break;
- case 4:
- case 5: /* DOS 5.x - like dos 4.x */
- case 6: /* DOS 6.x - like dos 4.x */
- entrylen = 59; /* DOS 4.x - I do not know what is in the
- * extra 6 bytes */
- break;
- default:
- /*
- tprintf("Sorry, cannot handle this version of MS-DOS");
- */
- return 1;
- }
-
- for (;;) {
- /* pointer to next file table */
- pnext = (char DFAR *) MK_FP(*(int DFAR *) (pfiletab + 2), *(int DFAR *) (pfiletab + 0));
- nfiles = *(int DFAR *) (pfiletab + 4);
- #ifdef DEBUG
- tprintf("\nFile table at %Fp entries for %d files\n", pfiletab, nfiles);
- #endif
- for (i = 0; i < nfiles; i++) {
-
- /*
- * cycle through all files, quit when we reach an
- * unused entry
- */
- entry = pfiletab + 6 + (i * entrylen);
- if (_osmajor >= 3) {
- name = entry + 32;
- strncpy(file, localcopy(name), 11);
- file[11] = '\0';
- numhandles = *(int DFAR *) (entry + 0);
- access = (int) *(char DFAR *) (entry + 2);
- length = *(long DFAR *) (entry + 17);
- offset = *(long DFAR *) (entry + 21);
- devinfo = *(int DFAR *) (entry + 5);
- progpsp = *(int DFAR *) (entry + 49);
- } else {
- name = entry + 4;
- strncpy(file, localcopy(name), 11);
- file[11] = '\0';
- numhandles = (int) *(char DFAR *) (entry + 0);
- access = (int) *(char DFAR *) (entry + 1);
- length = *(long DFAR *) (entry + 19);
- offset = *(long DFAR *) (entry + 36);
- devinfo = (int) *(char DFAR *) (entry + 27);
- }
- if ((strlen(file) > 0) && (numhandles > 0) && !(devinfo & 0x80)) {
- if(!heading) {
- tprintf("\n");
- tprintf(" Table of Open Files.\n");
- tprintf(" --------------------\n");
- tprintf("Name length offset hnd acc PSP device type/owner\n");
- tprintf("---- ------ ------ --- --- --- -----------------\n");
- heading++; /* header now printed */
- }
- tprintf("%8.8s.%3.3s %8ld %8ld %2d ",
- file, &file[8], length, offset, numhandles);
- switch (access) {
- case 0:
- tprintf("r ");
- break;
- case 1:
- tprintf("w ");
- break;
- case 2:
- tprintf("rw ");
- break;
- default:
- tprintf(" ");
- }
- if (_osmajor >= 3)
- tprintf("%04X ", progpsp);
- else
- tprintf("---- ");
- tprintf("drive %c: ", 'A' + (devinfo & 0x1F));
- if (devinfo & 0x8000)
- tprintf("(network) ");
- if (_osmajor >= 3) {
- /*
- * only DOS 3+ can find out
- * the name of the program
- */
- fnsplit(progname(progpsp), NULL, NULL, ownername, ownerext);
- tprintf(" [%s%s]\n", strlwr(ownername), strlwr(ownerext));
- } else {
- tprintf("\n");
- }
- }
- if (strlen(file) == 0)
- return 0;
- }
- pfiletab = pnext;
- }
- }
-
- /* Make a copy of a string pointed to by a far pointer */
- static char *
- localcopy(s)
- char DFAR *s;
- {
- static char localstring[256];
- char DFAR *p = s;
- char *l = localstring;
- int i = 0;
-
- while (*p != NULL && i++ < 255) {
- *l++ = *p++;
- }
-
- *l = '\0';
-
- return (localstring);
- }
-
- /*
- * Return a near pointer to a character string with the full path name of the
- * program whose PSP is given in the argument. If the argument is invalid,
- * this may return gibberish but I don't know how to tell Offset 0x2C in the
- * PSP in the segment address of the environment of a program. Beyond the
- * last environment string is a null marker, a word count (usually 1), then
- * the full pathname of the owner of the environment This only works for DOS
- * 3+
- */
- static char *
- progname(pid)
- unsigned int pid;
- {
- unsigned DFAR *envsegptr; /* Pointer to seg address of
- * environment */
- char DFAR *envptr; /* Pointer to pid's environment */
- unsigned DFAR *envsizeptr; /* Pointer to environment size */
- unsigned envsize;/* Size of pid's environment */
- unsigned ppid; /* Parent psp address */
-
- /* find the parent process psp at offset 0x16 of the psp */
- ppid = *(unsigned DFAR *) MK_FP(pid, 0x16);
-
- /* find the environment at offset 2Ch of the psp */
- envsegptr = (unsigned DFAR *) MK_FP(pid, 0x2C);
- envptr = (char DFAR *) MK_FP(*envsegptr, 0);
-
- /*
- * Make a pointer that contains the size of the environment block.
- * Must point back one paragraph (to the environments MCB plus three
- * bytes forward (to the MCB block size field).
- */
- envsizeptr = (unsigned DFAR *) MK_FP(*envsegptr - 1, 0x3);
- envsize = *envsizeptr * 16; /* x 16 turns it into bytes */
-
- while (envsize > 0) {
- /* search for end of environment block, or NULL */
- while (--envsize && *envptr++);
-
- /*
- * Now check for another NULL immediately following the first
- * one located and a word count of 0001 following that.
- */
- if (!*envptr && *(unsigned DFAR *) (envptr + 1) == 0x1) {
- envptr += 3;
- break;
- }
- }
-
- if (envsize > 0) {
- /* Owner name found - return it */
- return (localcopy(envptr));
- } else {
- if (pid == ppid) {
- /*
- * command.com doesn't leave it's name around, but if
- * pid = ppid then we know we have a shell
- */
- return ("-shell-");
- } else {
- return ("unknown");
- }
- }
- }
-
- #endif /*__TURBOC__*/
-
-
-
- /* Command history, see also pc.c - WG7J */
- void logcmd(cmd)
- char *cmd;
- {
- struct hist *new;
- char *cp;
-
- if(!Maxhistory) /* don't keep history */
- return;
-
- /* Get rid of \n; this is also done in cmdparse().
- * We HAVE to do this here, since the string is NOT null-terminated when
- * it comes from recv_mbuf() !!!! rip() makes it nullterminated.
- */
- rip(cmd);
- cp = cmd;
- while(*cp == ' ' || *cp == '\t')
- cp++;
- if(!*cp) /* Empty command */
- return;
-
- if(Histrysize < Maxhistory) { /* Add new one */
- Histrysize++;
- if(!Histry) { /* Empty list */
- /* Initialize circular linked list */
- Histry = mallocw(sizeof(struct hist));
- Histry->next = Histry->prev = Histry;
- } else {
- new = mallocw(sizeof(struct hist));
- /* Now link it in */
- Histry->next->prev = new;
- new->next = Histry->next;
- new->prev = Histry;
- Histry->next = new;
- Histry = new;
- }
- } else {
- /* Maximum number stored already, use the oldest entry */
- Histry = Histry->next;
- free(Histry->cmd);
- }
- Histry->cmd = strdup(cp);
- }
-
- static void freehistory ()
- {
- struct hist *h, *last;
-
- if((h = Histry) == NULL)
- return;
- do {
- free (h->cmd);
- last = h;
- h = h->prev;
- free (last);
- } while(h != Histry);
- Histry = NULL;
- Histrysize = 0;
- }
-
- int
- dohistory(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct hist *h;
- int num;
-
- if(argc > 1) {
- Maxhistory = atoi(argv[1]);
- freehistory ();
- return 0;
- }
- tprintf("Max recall %d\n",Maxhistory);
- if((h = Histry) == NULL)
- return 0;
- num = 0;
- do {
- tprintf("%.2d: %s\n",num++,h->cmd);
- h = h->prev;
- } while(h != Histry);
- return 0;
- }
-
-
- #if 0
- #ifndef LINUX
-
- /* This adds some additional checks to the fopen()
- * in the Borland C++ Run Time Library.
- * It fixes problem with users trying to open system devices like
- * CON, AUX etc and hang a system.
- * WG7J, 930205
- */
- #undef fopen
- FILE _FAR *_Cdecl fopen(const char _FAR *__path, const char _FAR *__mode);
-
- static char *InvalidName[] = {
- "NUL",
- "CON",
- "AUX",
- "PRN",
- "LPT1",
- "LPT2",
- "LPT3",
- "COM1",
- "COM2",
- "COM3",
- "COM4",
- "MOUSE$",
- "CLOCK$",
- NULLCHAR,
- };
-
- #ifndef __TURBOC__
- FILE *newfopen (const char *filename, const char *type) {
- int i;
-
- for(i=0;InvalidName[i] != NULLCHAR;i++)
- if(stricmp(InvalidName[i],filename) == 0)
- return NULL;
-
- return fopen (filename, type);
- }
- #endif
- #endif /* LINUX */
- #endif
-
- #if defined(__TURBOC__) && !defined(__BORLANDC__)
- /* N5KNX: TurboC 2.0 lacks _setcursortype(), which we supply here for dorepeat */
- void _setcursortype(style)
- int style;
- {
- /* From TurboC++ conio.h: */
- #define _NOCURSOR 0
- #define _SOLIDCURSOR 1
- #define _NORMALCURSOR 2
-
- /* Int 0x10 reg cx codes: */
- #define STD_CURSOR 0x0607
- #define BLK_CURSOR 0x0006
- #define NO_CURSOR 0x2607
-
- union REGS regs;
-
- if (style == _NOCURSOR) regs.x.cx = NO_CURSOR;
- else if (style == _SOLIDCURSOR) regs.x.cx = BLK_CURSOR;
- else if (style == _NORMALCURSOR) regs.x.cx = STD_CURSOR;
- else return;
- regs.x.ax = 0x0100; /* set cursor */
- int86(0x10, ®s, ®s);
- }
- #endif
-
- /* Repeat a command - taken from 930104 KA9Q NOS
- WA3DSP 1/93
- */
- int
- dorepeat(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int32 interval;
- int ret;
- struct session *sp;
-
- if(isdigit(argv[1][0])){
- interval = atol(argv[1]);
- argc--;
- argv++;
- } else {
- interval = MSPTICK;
- }
- if((sp = newsession(argv[2],REPEAT,0)) == NULLSESSION){
- tputs("Too many sessions\n");
- return 1;
- }
- _setcursortype(_NOCURSOR);
- while(sp==Current){
- /* clrscr(); */
- /* gotoxy seems to work better - turn cursor off?? */
- gotoxy(1,1);
- ret = subcmd(Cmds,argc,argv,p);
- if(ret != 0 || mspause(interval) == -1)
- break;
- }
- _setcursortype(_NORMALCURSOR);
- freesession(sp);
- return 0;
- }
-
-
-